package com.tc.infinitechat.authenticationservice.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tc.infinitechat.authenticationservice.constants.redis.RedisConstants;
import com.tc.infinitechat.authenticationservice.constants.user.UserErrorEnum;
import com.tc.infinitechat.authenticationservice.data.user.login.LoginRequest;
import com.tc.infinitechat.authenticationservice.data.user.login.LoginResponse;
import com.tc.infinitechat.authenticationservice.data.user.logincode.LoginCodeRequest;
import com.tc.infinitechat.authenticationservice.data.user.logincode.LoginCodeResponse;
import com.tc.infinitechat.authenticationservice.data.user.register.RegisterRequest;
import com.tc.infinitechat.authenticationservice.data.user.register.RegisterResponse;
import com.tc.infinitechat.authenticationservice.data.user.update.UpdateAvatarRequest;
import com.tc.infinitechat.authenticationservice.data.user.update.UpdateAvatarResponse;
import com.tc.infinitechat.authenticationservice.exception.BusinessException;
import com.tc.infinitechat.authenticationservice.model.User;
import com.tc.infinitechat.authenticationservice.service.UserService;
import com.tc.infinitechat.authenticationservice.mapper.UserMapper;
import com.tc.infinitechat.authenticationservice.utils.JsonUtils;
import com.tc.infinitechat.authenticationservice.utils.RandomNicknameUtil;
import com.tc.infinitechat.authenticationservice.utils.jwt.JwtUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;

import java.util.Date;
import java.util.Objects;

/**
 *
 */
@Service
@Slf4j
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
    implements UserService{

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public RegisterResponse register(RegisterRequest request) {
        // 1. 校验用户是否存在
        String phone = request.getPhone();
        String code = request.getCode();

        // mq
//        QueryWrapper<User> queryWrapper = new QueryWrapper<>();
//        queryWrapper.eq("phone", request.getPhone());
//        long count = this.count(queryWrapper);
//        if (count > 0) {
//            throw new BusinessException(UserErrorEnum.USER_ALREADY_REGISTER);
//        }

        User user = userMapper.selectbyPhone(phone);
        if (Objects.nonNull(user)) {
            throw new BusinessException(UserErrorEnum.USER_ALREADY_REGISTER);
        }

        // 2. 查询redis 查看提交的code 是否匹配
        String codeKey = RedisConstants.getCodeKey(phone);
        String codeFromRedis = redisTemplate.opsForValue().get(codeKey);
        log.info("codekey: {}, 读取到的验证码：{}", codeKey, codeFromRedis);

        if (StringUtils.isBlank(codeFromRedis) || !StringUtils.equals(code, codeFromRedis)) {
            throw new BusinessException(UserErrorEnum.CHECK_CODE_NOT_RIGHT);
        }
        Snowflake snowflake = IdUtil.getSnowflake(1, 1);
        String encryptedPassword = DigestUtils.md5DigestAsHex(request.getPassword().getBytes());
        user = new User();
        user.setUserId(snowflake.nextId());
        user.setPassword(encryptedPassword);
        user.setPhone(phone);
        user.setUserName(RandomNicknameUtil.generate());
        user.setCreatedAt(new Date());
        user.setUpdatedAt(new Date());
//        userMapper.insert(user);
        this.save(user);
        return new RegisterResponse(phone);
    }

    @Override
    public LoginResponse login(LoginRequest request) {
        String phone = request.getPhone();
        String password = request.getPassword();
        String encryptedPassword = DigestUtils.md5DigestAsHex(password.getBytes());

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);
        User user = this.getOne(queryWrapper);

        if (Objects.isNull(user)) {
            throw new BusinessException(UserErrorEnum.USER_NOT_FOUND);
        }
        String queryPassword = user.getPassword();
        if (!encryptedPassword.equals(queryPassword)) {
            throw new BusinessException(UserErrorEnum.PASSWORD_NOT_RIGHT);
        }

        LoginResponse loginResponse = LoginResponse.builder().build();
        BeanUtils.copyProperties(user, loginResponse);

        // 获取token
        loginResponse.setToken(JwtUtil.generate(String.valueOf(user.getUserId())));

        return loginResponse;
    }

    @Override
    public LoginCodeResponse loginCode(LoginCodeRequest request) {
        String phone = request.getPhone();
        String code = request.getCode();

        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getPhone, phone);
        User user = this.getOne(queryWrapper);

        if (Objects.isNull(user)) {
            throw new BusinessException(UserErrorEnum.USER_NOT_FOUND);
        }

        String codeFromRedis = redisTemplate.opsForValue().get(RedisConstants.getCodeKey(phone));
        if (StringUtils.isBlank(codeFromRedis) || !StringUtils.equals(code, codeFromRedis)) {
            throw new BusinessException(UserErrorEnum.CHECK_CODE_NOT_RIGHT);
        }

        LoginCodeResponse loginCodeResponse = LoginCodeResponse.builder().build();
        BeanUtils.copyProperties(user, loginCodeResponse);

        // 获取token
        loginCodeResponse.setToken(JwtUtil.generate(String.valueOf(user.getUserId())));

        return loginCodeResponse;
    }

    @Override
    public UpdateAvatarResponse updateAvatar(String id, UpdateAvatarRequest request) {
        //
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserId, Long.valueOf(id));
        User user = this.getOne(queryWrapper);
        if (Objects.isNull(user)) {
            throw new BusinessException(UserErrorEnum.USER_NOT_FOUND);
        }
        user.setAvatar(request.getAvatarUrl());
        boolean isUpdate = this.updateById(user);
        if (!isUpdate) {
            throw new BusinessException(UserErrorEnum.AVATAR_UPDATE_ERROR);
        }

        UpdateAvatarResponse updateAvatarResponse = new UpdateAvatarResponse();
        BeanUtils.copyProperties(user, updateAvatarResponse);
        return updateAvatarResponse;
    }
}




